var CONSTS = require('../util/consts');
var moment = require('moment');
var async = require('async');
var Common = require('../util/common');
var CONFIG = require('../config/config').Config;
// var nodemailer = require('nodemailer');
var thenjs = require('thenjs');
var crypto = require("crypto");
var validator = require('validator');
var models = require('../models');
var fs = require('fs-extra');

models.User.findOne({
    name: 'admin'
}, function(err, user) {
    if (!err && !user) {
        var avatar = Common.randomAvatar();
        var pwd = '123456';

        models.User.update({
            name: 'admin'
        }, {
            "$set": {
                group: 'admin',
                name: 'admin',
                nickname: 'admin',
                pwd: models.User.hashPwd(pwd),
                created: moment().utc().format()
            }
        }, {
            upsert: true
        }, function(err, numberAffected, raw) {
            if (err) {
                console.log(err);
                return;
            }

            console.log('create sewing admin user successfully');
        });
    }
});

var handler = module.exports;

handler.dry = function(u) {
    u.pwd = u.__v = void 0; // xxx
    return u;
};

handler.clearSess = function(u, res, callback) {
    res.clearCookie('sess');
    return callback(null);

};

handler.createSess = function(u, res, callback) {
    return thenjs((function() {
        return function(cont) {
            var sess;
            if (u.sess) {
                return cont(null, u);
            } else {
                sess = crypto.createHash("sha1").update('' + u._id + u.pwd).digest("hex");
                u.sess = sess;
                u.save(function(err, u) {
                    return cont(err, u);
                });
            }
        };
    })()).then((function() {
        return function(cont, u) {
            res.cookie("sess", u.sess, {
                path: '/',
                httpOnly: true,
                signed: true,
                maxAge: 31536000000
            });
            return callback(null, u);
        };
    })()).fail((function() {
        return function(cont, err) {
            return callback(err);
        };
    })());
};

exports.signIn = function(req, res, next) {
    var opt = {};
    var body = req.body;
    var name = Common.cleanString(body.username);
    var pwd = Common.cleanString(body.password);

    thenjs(function(cont) {
        models.User.findOne({
            name: name
        }).exec(function(err, u) {
            cont(err, u);
        });
    }).then(function(cont, u) {
        if (!u) {
            res.send(Common.errorHandle(1, '用户不存在'));
            return;
        }

        var today = new Date();

        if (
            (today.getYear() != u.lastPwdTryTime.getYear()) ||
            (today.getMonth() != u.lastPwdTryTime.getMonth()) ||
            (today.getDate() != u.lastPwdTryTime.getDate())
        ) {
            u.pwdFailureTimes = 0;
        } else if (u.pwdFailureTimes >= 6) {
            res.send(Common.errorHandle(3, '已经尝试6次以上'));
            return;
        }

        u.lastPwdTryTime = today;

        if (!pwd || !u.isPwd(pwd, u)) {
            u.pwdFailureTimes += 1;
            u.save(function(err) {});
            res.send(Common.errorHandle(4, '密码错误, 还可以尝试' + (6 - u.pwdFailureTimes) + '次'));
            return;
        }

        u.pwdFailureTimes = 0;

        if (u.sess) {
            u.save(function(err) {}); // xxx: createSess不会调用
        }

        handler.createSess(u, res, cont);
    }).then(function(cont, u) {
        res.send({
            status: 0,
            msg: handler.dry(u)
        });
        return;
    }).fail(function(cont, err) {
        next(err);
        return;
    });
};
exports.signUp = function(req, res, next) { //暂时先这样
    var body = req.body;
    var name = body.name;
    var pwd = body.pwd;
    var mail = body.email;



    if (!mail || !validator.isEmail(mail)) {
        res.send(Common.errorHandle(2, '邮箱格式不正确'));
        return;
    } else if (!name || !pwd || !(2 <= Common.getByteLen(name) && Common.getByteLen(name) <= 15 && 6 <= pwd.length && pwd.length <= 20)) {
        res.send(Common.errorHandle(3, '用户名(2-15)或密码(6-20)长度不正确'));
        return;
    }

    if (/^[0-9_].*/.test(name)) {
        res.send(Common.errorHandle(4, '用户名不能以数字或下划线开头'));
        return;
    }

    if (/[\s><,.\]\[{}?\/+=|\\\'\":;~!|@#*$%^&()`]|(｛)|(｝)|(！)|(｜)|(～)|(｀)|(-)/.test(name)) {
        res.send(Common.errorHandle(5, '用户名包含非法字符'));
        return;
    }

    mail = validator.normalizeEmail(validator.trim(mail));

    if (Common.isTrimmedEmpty(nickname)) {
        nickname = name;
    }

    thenjs(function(cont) {
        models.User.findOne({
            mail: mail
        }, function(err, u) {
            cont(err, u);
        })
    }).then(function(cont, user) {
        if (user) {
            res.send(Common.errorHandle(6, '该邮箱已被注册'));
            return;
        }

        models.User.findOne({
            name: name
        }, function(err, user) {
            cont(err, user)
        })
    }).then(function(cont, user) {
        if (user) {
            res.send(Common.errorHandle(7, '用户名已存在'));
            return;
        }



        models.User.update({
            mail: mail
        }, {
            "$set": {
                group: 'normal',
                mail: mail,
                name: name,
                nickname: nickname,
                pwd: models.User.hashPwd(pwd),
                verified: false,
                created: moment().utc().format()
            }
        }, {
            upsert: true
        }, function(err, numberAffected, raw) {
            if (err) {
                cont(err, null);
                return;
            }

            models.User.findOne({
                mail: mail
            }, function(err, u) {
                cont(err, u);
            });
        });
    }).then(function(cont, u) {
        handler.createSess(u, res, cont);
        res.json(CONSTS.HTTPOK, {
            status: 0,
            msg: {}
        });
        return;
    }).fail(function(cont, err) {
        next(err);
    });
}
exports.signOut = function(req, res, next) {
    handler.clearSess(req.u, res, function(err) {
        if (err) {
            next(err);
            return;
        }

        res.send({
            status: 0,
            msg: {}
        });
    });
};

exports.modifyuser = function(req, res, next) {
    var u = req.u;
    var body = req.body;
    var nickname = body.username;
    var email = body.email;
    var local = body.local;
    var blog = body.blog;
    var description = body.description;

    models.User.findOne({
        _id: u._id
    }, function(err, user) {
        if (err || !user) {
            res.send(Common.errorHandle(2, 'db error'));
            return;
        } else {
            user.nickname = nickname;
            user.email = email;
            user.local = local;
            user.otherblog = blog;
            user.description = description;

            user.save(function(err) {
                if (err) {
                    res.send(Common.errorHandle(2, 'db error'));
                    return;
                } else {
                    res.json(CONSTS.HTTPOK, {
                        status: 0,
                        msg: {}
                    });
                }
            });
        }
    });
}

exports.modifyavatar = function(req, res, next) {
    var u = req.u;
    var body = req.body;
    var avatar = body.avatar;

    models.User.findOne({
        _id: u._id
    }, function(err, user) {
        if (err || !user) {
            res.send(Common.errorHandle(2, 'db error'));
            return;
        } else {
            user.avatar = avatar;

            user.save(function(err) {
                if (err) {
                    res.send(Common.errorHandle(2, 'db error'));
                    return;
                } else {
                    res.json(CONSTS.HTTPOK, {
                        status: 0,
                        msg: {}
                    });
                }
            });
        }
    });
}

exports.modifyavatar = function(req, res, next) {
    var u = req.u;
    var body = req.body;
    var coverplan = body.coverplan;

    models.User.findOne({
        _id: u._id
    }, function(err, user) {
        if (err || !user) {
            res.send(Common.errorHandle(2, 'db error'));
            return;
        } else {
            user.coverplan = coverplan;

            user.save(function(err) {
                if (err) {
                    res.send(Common.errorHandle(2, 'db error'));
                    return;
                } else {
                    res.json(CONSTS.HTTPOK, {
                        status: 0,
                        msg: {}
                    });
                }
            });
        }
    });
}

exports.changepwd = function(req, res, next) {
    if (!req.u._id) {
        res.send(Common.errorHandle(400, '登录超时'));
        return;
    }

    var body = req.body;
    var oldpwd = body.oldpwd;
    var pwd = body.newpwd;

    if (!Common.isDefined(oldpwd) || !Common.isDefined(pwd)) {
        res.send(Common.errorHandle(1, '密码不能为空'));
        return;
    }

    models.User.findOne({
        _id: req.u._id
    }, function(err, user) {
        if (err || !user) {
            res.send(Common.errorHandle(2, 'db error'));
            return;
        }

        if (!user.isPwd(oldpwd, user)) {
            res.send(Common.errorHandle(3, 'wrong old password'));
            return;
        }

        user.pwd = models.User.hashPwd(pwd);
        user.sess = crypto.createHash("sha1").update('' + user._id + user.pwd).digest("hex");

        user.save(function(err) {
            if (err) {
                res.send(Common.errorHandle(2, 'db error'));
                return;
            }

            handler.clearSess(user, res, function(err) {
                if (err) {
                    next(err);
                    return;
                }

                res.send({
                    status: 0,
                    msg: {}
                });
            });
        });
    });
};

exports.upload = function(req, res, next) {

    var oldfilePath = '';
    var kind = '';
    var filename = '';
    var newfilePath = '';

    if (req.files['coverplan']) {
        oldfilePath = req.files['coverplan'].path;
        kind = oldfilePath.split(".")[1];
        filename = req.files['coverplan'].name;
        newfilePath = '/../public/img/' + filename + '.' + kind;
    }

    if (req.files['avatar']) {
        oldfilePath = req.files['avatar'].path;
        kind = oldfilePath.split(".")[1];
        filename = req.files['avatar'].name;
        newfilePath = '/../public/img/' + filename + '.' + kind;
    }

    fs.rename(oldfilePath, __dirname + newfilePath, function(err) {
        if (err) {
            res.send({
                error: 'Upload fail!'
            });
            return;
        }

        models.User.findOne({
            _id: req.u._id
        }, function(err, user) {
            if (err) {
                res.send({
                    error: 'Upload fail!'
                });
                return;
            }

            user[filename] = '/img/' + filename + '.' + kind;

            user.save(function(err, user) {
                if (err) {
                    res.send({
                        error: 'Upload fail!'
                    });
                    return;
                }

                res.send({
                    initialPreviewConfig: [{
                        caption: '/img/' + filename + '.' + kind,
                        width: '300px',
                        url: '', // server delete action 
                        key: 100,
                        extra: {
                            id: 100
                        }
                    }]
                });
            });
        });

    })

};